【CloudFormation】SSM ステートマネージャーを使ってCloudWatch Agentのインストールとログ出力設定を自動化してみる
Systems Manager State Manager(以下ステートマネージャー)はSSM管理下のインスタンスのあるべき状態を定義できる機能です。
インスタンスが起動したタイミングで、必ず設定しておきたい状態をステートマネージャーで定義することでアカウント内の統制をとることが可能です。
今回はこのステートマネージャーを使うことで、CloudWatch AgentのインストールとCloudWatch Logsへのログ出力設定を自動化してみました。
作成するもの
こんな感じのイメージです。Systems Mmanagerのリソースを展開したあと、EC2インスタンス(Linux/Windows)を作成してCloudWatch Logsにログが出力されるか確認します。
SSMドキュメント
自作のInstallAndManageCloudWatchDocument
を作成してます。AWS提供のドキュメントを組み合わせてCloudWatch Agentのインストールとログ出力設定を行います。
また、Amazon Linux 2023ではrsyslog
がインストールされておらず、これまでの/var/log/messages
などのログが出力されなくなっているので、Linuxの場合はインストールする処理も入れています。
Amazon Linux 2023の詳細については以下をご参照ください。
Amazon Linux 2023とAmazon Linux2のデフォルトで起動しているサービスやインストールされているパッケージを比較してみた | DevelopersIO
- AWS-ConfigureAWSPackage
- CloudWatch Agentをインストール
- AmazonCloudWatch-ManageAgent
- CloudWatch Agentのログ出力設定
- 設定値はパラメータストアから取得
- Windows/Linuxのプラットフォームで処理を分岐
- CloudWatch Agentのログ出力設定
- AWS-RunShellScript(Linuxの場合のみ)
- rsyslogをインストール・起動
ステートマネージャー
以下の設定で行います。 - 実行対象 - 全てのインスタンス - スケジュール - 1回のみ(インスタンス起動時のみ)
パラメータストア
ログ出力の定義値を登録します。今回はLunixとWindowsで以下2つです。
- AmazonCloudWatch-Linux-syslog
- /var/log/messagesを出力
- AmazonCloudWatch-Windows-syslog
- Systemを出力
やってみる
CloudFormationスタックの作成
Systems ManagerのリソースはCloudFormationテンプレートで作成しました。
以下のテンプレートを使ってスタックを作成してください。
ちょっと長いので折りたたみます。(↓クリックして開いてね)
CloudFormationテンプレート
AWSTemplateFormatVersion: "2010-09-09" Parameters: LogGroupPrefix: Type: "String" Default: "oslog-linux-syslog" AllowedValues: ["oslog-linux-syslog"] LogGroupPrefixWindows: Type: "String" Default: "oslog-windows-syslog" AllowedValues: ["oslog-windows-syslog"] RetentionDays: Description: The number of days to retain the log events in the specified log group. Type: Number Default: 30 AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365] Resources: # 取得する syslog を定義する SSM Parameter ## Linux SSMParameterLinuxLogs: Type: "AWS::SSM::Parameter" Properties: Name: !Sub "AmazonCloudWatch-Linux-syslog" Description: "SSM Parameter for Linux to export syslog." DataType: "text" Tier: "Standard" Type: "String" Value: !Sub |- { "agent": { "run_as_user": "root" }, "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/var/log/messages", "log_group_name": "${LogGroupPrefix}-${AWS::Region}/var/log/messages", "log_stream_name": "{instance_id}", "retention_in_days": ${RetentionDays} } ] } } } } ## Windows SSMParameterWindowsLogs: Type: "AWS::SSM::Parameter" Properties: Name: !Sub "AmazonCloudWatch-Windows-syslog" Description: "SSM Parameter for Windows to export syslog." DataType: "text" Tier: "Standard" Type: "String" Value: !Sub |- { "agent": { "run_as_user": "root" }, "logs": { "logs_collected": { "windows_events": { "collect_list": [ { "event_format": "xml", "event_levels": [ "WARNING", "ERROR", "CRITICAL" ], "event_name": "System", "log_group_name": "${LogGroupPrefixWindows}-${AWS::Region}/System", "log_stream_name": "{instance_id}", "retention_in_days": ${RetentionDays} } ] } } } } InstallAndManageCloudWatchDocument: Type: "AWS::SSM::Document" Properties: DocumentType: Command Name: InstallAndManageCloudWatchDocument UpdateMethod: NewVersion Content: schemaVersion: "2.2" description: "The AWS-InstallAndManageCloudWatch command document installs the Amazon CloudWatch agent and manages the configuration of the agent for Amazon EC2 instances." mainSteps: - name: installCWAgent action: "aws:runDocument" inputs: documentType: SSMDocument documentPath: AWS-ConfigureAWSPackage documentParameters: action: Install name: AmazonCloudWatchAgent # Amazon Linux 2023では rsyslog が未インストール - name: installRsyslogLinux action: "aws:runDocument" precondition: StringEquals: - platformType - Linux inputs: documentType: SSMDocument documentPath: AWS-RunShellScript documentParameters: commands: - yum install rsyslog -y - sudo systemctl enable rsyslog - sudo systemctl restart rsyslog - name: manageCWAgentLinux action: "aws:runDocument" precondition: StringEquals: - platformType - Linux inputs: documentType: SSMDocument documentPath: AmazonCloudWatch-ManageAgent documentParameters: action: configure mode: ec2 optionalConfigurationSource: ssm optionalConfigurationLocation: !Ref SSMParameterLinuxLogs optionalRestart: "yes" - name: manageCWAgentWindows action: "aws:runDocument" precondition: StringEquals: - platformType - Windows inputs: documentType: SSMDocument documentPath: AmazonCloudWatch-ManageAgent documentParameters: action: configure mode: ec2 optionalConfigurationSource: ssm optionalConfigurationLocation: !Ref SSMParameterWindowsLogs optionalRestart: "yes" SystemAssociationForInstallAndConfigureCloudWatchAgent: Type: "AWS::SSM::Association" Properties: Name: Ref: InstallAndManageCloudWatchDocument AssociationName: ManageCloudWatchAgent ScheduleExpression: Ref: "AWS::NoValue" Targets: - Key: InstanceIds Values: - "*"
パラメータとしてロググループのプレフィクスと保持期間が設定できます。今回はすべてデフォルトのまま進めます。
スタックの作成が完了したらOKです。
EC2の起動
起動するEC2は以下が前提です。
- SSM管理下であること (参考:AWS Systems Manager のセットアップ - AWS Systems Manager)
- CloudWatch Logsへのログ出力する権限があること(CloudWatchAgentServerPolicy相当)
今回は以下のAMIを使います。
- Amazon linux 2
- Amazon linux 2023
- Windows Server 2022 Base
IAMロールの権限が不足しないよう注意してください。最小権限であれば、以下2つのポリシーをアタッチします。
- CloudWatchAgentServerPolicy
- AmazonSSMManagedInstanceCore
以下3つのインスタンスを起動して、すべてにIAMロールをアタッチしました。
CloudWatch Logsの確認
少し時間をおいてCloudWatch Logsを見ると、CloudWatch Logsのロググループが作成されているのを確認できました。
Linux側は2つのインスタンスを起動したので、ログストリームに2つのインスタンスIDが作成されています。
Amazon Lunux 2023のインスタンスもログが出力できたので、rsyslog
のインストールと起動も問題ないようです。
無事ステートマネージャーを使って、EC2のCloudWatch Agentのインストールとログ出力設定を自動化できました。
まとめ
ステートマネージャーを使ってCloudWatch Agentのインストールとログ出力設定を自動化してみました。
この仕組みはEC2がSSM管理になっていることが前提なので、以下のようなConfigルールで非管理状態のものを検知できる仕組みがあるとよさそうです。
ec2-instance-managed-by-systems-manager - AWS Config
SSMドキュメントをうまく書ければ他にも色々できるので、管理方法に合わせたものを作れると運用が楽になります!EC2管理に統制をかけたい場合は是非試してみてください。